package com.sjft.cloud.commons.support.xss.util;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.owasp.validator.html.*;

import java.nio.charset.StandardCharsets;

@Slf4j
public class XssUtil {
    protected static AntiSamy antiSamy;

    static {
        try {
            Policy policy = Policy.getInstance(XssUtil.class.getResourceAsStream("/antisamy.xml"));
            antiSamy = new AntiSamy(policy);
        } catch (PolicyException exception) {
            log.error("Xss工具初始化失败！ - {}", exception);
        }

    }

    public static byte[] cleanXSS(byte[] bytes) {
        String body = new String(bytes, StandardCharsets.UTF_8);
        if (JSONUtil.isJson(body)) {
            if (JSONUtil.isJsonArray(body)) {
                JSONArray jsonArray = new JSONArray();
                JSONUtil.parseArray(body).forEach(object -> {
                    if (object instanceof String) {
                        String value = XssUtil.cleanXSS((String) object);
                        jsonArray.add(value);
                    } else if (object instanceof JSONObject) {
                        JSONObject jsonObject = (JSONObject) object;
                        clear(jsonObject);
                        jsonArray.add(jsonObject);
                    } else {
                        jsonArray.add(object);
                    }
                });
                return jsonArray.toString().getBytes();
            } else {
                JSONObject jsonObject = JSONUtil.parseObj(body);
                clear(jsonObject);
                return jsonObject.toString().getBytes();
            }
        } else {
            return XssUtil.cleanXSS(body).getBytes();
        }
    }

    private static JSONObject clear(JSONObject jsonObject) {
        jsonObject.forEach((k, v) -> {
            if (v instanceof String) {
                //此处清理一切不安全的字符串
                String newValue = XssUtil.cleanXSS((String) v);
                jsonObject.put(k, newValue);
            }
        });
        return jsonObject;
    }

    public static String cleanXSS(String content) {
        try {
            CleanResults cr = antiSamy.scan(content);
            content = cr.getCleanHTML();
        } catch (PolicyException | ScanException exception) {
            log.error("Xss处理失败！ - {}", exception);
        }
        return content;
    }


}
